// 引入pixiJs的包
import * as PIXI from 'pixi.js';
import Loader from './Loader';
import PlayButton from './PlayButton';
import Background from './Background';
import ReelsContainer from './ReelsContainer';
import Scoreboard from './Scoreboard';
import VictoryScreen from './VictoryScreen';
import ReelBox from './ReelBox';

// 默认导出游戏构造函数
export default class Game {
    public app: PIXI.Application;
    private playBtn: PlayButton;
    private reelsContainer: ReelsContainer;
    private scoreboard: Scoreboard;
    private victoryScreen: VictoryScreen;
    private reelBox: ReelBox;

    constructor() {
        // 创建Pixi应用程序
        this.app = new PIXI.Application({
            width: window.innerWidth,
            height: window.innerHeight,
            antialias: true,     // 消除锯齿
            transparent: false,  // 背景不透明
            resolution: 1,       // 像素设置
        });
        // 将Pixi自动为您创建的画布添加到HTML文档中
        window.document.body.appendChild(this.app.view);
        // 执行加载器构造函数
        new Loader(this.app, this.init.bind(this));
    }

    // 初始化方法(当资源加载完成时触发)
    private init() {
        // 调用创建'游戏场景'的方法
        this.createScene();
        // 调用创建'卷轴盒子'的方法
        this.createReelBox()
        // 调用创建'开始按钮'的方法
        this.createPlayButton();
        // 调用创建'卷轴列表'的方法
        this.createReels();
        // 调用创建'记分板'的方法
        this.createScoreboard();
        // 调用创建'获胜场景'的方法
        this.createVictoryScreen();
        // 调用检查用户目前持有的金额是否允许下注的方法
        this.checkUserMoney()
    }

    // 创建'游戏场景'的方法
    private createScene() {
        // 执行'背景'构造函数创建'背景'对象
        const bg = new Background(this.app.loader, this.app);
        // 将'背景'对象身上挂载的'游戏背景'容器添加到舞台上
        this.app.stage.addChild(bg.container);
    }

    // 创建'卷轴盒子'的方法
    private createReelBox() {
        // 执行'卷轴盒子'构造函数创建'卷轴盒子'对象
        this.reelBox = new ReelBox(this.app.loader, this.app)
        // 将'卷轴盒子'对象身上挂载的'卷轴盒子'容器添加到舞台上
        this.app.stage.addChild(this.reelBox.container);
    }

    // 创建'开始按钮'的方法
    private createPlayButton() {
        // 执行'开始按钮'构造函数创建'开始按钮'对象
        this.playBtn = new PlayButton(this.app, this.handleStart.bind(this));
        // 将'开始按钮'对象身上挂载的'开始按钮'精灵添加到舞台上
        this.app.stage.addChild(this.playBtn.sprite);
    }

    // 创建'卷轴列表'的方法
    private createReels() {
        // 执行'卷轴列表容器'构造函数创建'卷轴列表容器'对象
        this.reelsContainer = new ReelsContainer(this.app, this.reelBox.hornContainer);
        // 将'卷轴列表容器'对象身上挂载的'卷轴列表'容器添加到舞台上
        this.reelBox.hornContainer.addChild(this.reelsContainer.container)
    }

    // 创建'记分板'的方法
    private createScoreboard() {
        // 执行'记分板'构造函数创建'记分板'对象
        this.scoreboard = new Scoreboard(this.app);
        // 将'记分板容器'对象身上挂载的'记分板'容器添加到舞台上
        this.app.stage.addChild(this.scoreboard.container);
    }

    // 创建'获胜场景'的方法
    private createVictoryScreen() {
        // 执行'获胜场景'构造函数创建'获胜场景'对象
        this.victoryScreen = new VictoryScreen(this.app);
        // 将'获胜场景'对象身上挂载的'获胜场景'容器添加到舞台上
        this.app.stage.addChild(this.victoryScreen.container);
    }

    // 处理函数,当'开始按钮'精灵被点击时触发
    async handleStart() {
        // 调用'记分牌'对象上的'减量'方法
        this.scoreboard.decrement();
        // 调用'开始按钮'对象上的'设置禁止状态'方法
        this.playBtn.setDisabled();
        // 调用'卷轴列表容器'对象身上的快速旋转方法,并在旋转方法完成时,执行回调函数
        await this.reelsContainer.spin().then(this.processSpinResult.bind(this));
    }

    // 处理函数,当卷轴旋转完成时触发
    private processSpinResult(winMode: number) {
        // 如果结果是玩家获利
        if (winMode > -1) {
            // 调用'记分板'对象上的加分方法
            const winPlusPoints = this.scoreboard.increment();
            // 调用'遮罩层'对象上的显示获胜场景方法
            this.victoryScreen.show(winMode, winPlusPoints);
        }
        // 如果用户完成本次游戏后,不缺钱的话,调用'开始按钮'对象身上的结束禁止状态方法
        if (!this.scoreboard.outOfMoney) this.playBtn.setEnabled();
    }

    // 检查用户分数是否允许下注的方法
    private checkUserMoney() {
        // 如果用户当前为缺钱状态,则将开始按钮设置为禁止状态
        if (this.scoreboard.outOfMoney) this.playBtn.setDisabled();
    }
}
